package com.ellen.mac.chatdemo.fragment;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.avos.avoscloud.AVException;
import com.avos.avoscloud.AVFile;
import com.avos.avoscloud.ProgressCallback;
import com.avos.avoscloud.SaveCallback;
import com.avos.avoscloud.im.v2.AVIMConversation;
import com.avos.avoscloud.im.v2.AVIMException;
import com.avos.avoscloud.im.v2.AVIMMessage;
import com.avos.avoscloud.im.v2.AVIMMessageOption;
import com.avos.avoscloud.im.v2.callback.AVIMConversationCallback;
import com.avos.avoscloud.im.v2.callback.AVIMMessagesQueryCallback;
import com.avos.avoscloud.im.v2.messages.AVIMAudioMessage;
import com.avos.avoscloud.im.v2.messages.AVIMImageMessage;
import com.avos.avoscloud.im.v2.messages.AVIMTextMessage;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.ellen.mac.chatdemo.R;
import com.ellen.mac.chatdemo.adpter.ChatAdapter;
import com.ellen.mac.chatdemo.adpter.GalleryAdapter;
import com.ellen.mac.chatdemo.adpter.NewChatAdapter;
import com.ellen.mac.chatdemo.adpter.VoiceAdpter;
import com.ellen.mac.chatdemo.comment.BaseApp;
import com.ellen.mac.chatdemo.event.InputBottomBarEvent;
import com.ellen.mac.chatdemo.event.InputBottomBarRecordEvent;
import com.ellen.mac.chatdemo.event.InputBottomBarTextEvent;
import com.ellen.mac.chatdemo.event.MessageResendEvent;
import com.ellen.mac.chatdemo.event.MessageUpdatedEvent;
import com.ellen.mac.chatdemo.event.TypeMessageEvent;
import com.ellen.mac.chatdemo.model.DataMP3Bean;
import com.ellen.mac.chatdemo.model.DataPhotoBean;
import com.ellen.mac.chatdemo.model.TeacherData;
import com.ellen.mac.chatdemo.model.VoiceItem;
import com.ellen.mac.chatdemo.utils.ChatKit;
import com.ellen.mac.chatdemo.utils.LogUtils;
import com.ellen.mac.chatdemo.utils.NotificationUtils;
import com.ellen.mac.chatdemo.view.NewInputBottomBar;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.yanzhenjie.album.Action;
import com.yanzhenjie.album.Album;
import com.yanzhenjie.album.AlbumFile;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * Created by j on 2017/12/13.
 */

public class NewPageFragment extends Fragment implements BaseQuickAdapter.OnItemChildLongClickListener {

    protected AVIMConversation imConversation;
    private static final int REQUEST_IMAGE_PICK = 2;
    /**
     * 底部的输入栏
     */
    protected NewInputBottomBar inputBottomBar;
    private RecyclerView mRecyclerView, voiceRecycler;
    private GalleryAdapter mAdapter;
    private VoiceAdpter mVoiceAdapter;
    private List<AlbumFile> files;
    private List<VoiceItem> paths;
    private List<DataPhotoBean> images = new ArrayList<>();
    private List<DataMP3Bean> audio = new ArrayList<>();

    /**
     * 负责下拉刷新的 SwipeRefreshLayout
     */
    protected SwipeRefreshLayout refreshLayout;
    /**
     * recyclerView 对应的 Adapter
     */
    protected NewChatAdapter itemAdapter;
    protected RecyclerView new_recyclerView;
    protected LinearLayoutManager layoutManager;
    private int count = 0;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.newpage_fragment, container, false);
        inputBottomBar = view.findViewById(R.id.inputbottombar);
        //得到控件
        mRecyclerView = view.findViewById(R.id.id_recyclerview_horizontal);
        voiceRecycler = view.findViewById(R.id.voice_recycler);
        //设置布局管理器
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
        linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        mRecyclerView.setLayoutManager(linearLayoutManager);
        //设置适配器
        files = new ArrayList<>();
        mAdapter = new GalleryAdapter(R.layout.image_item, files, getActivity());
        mRecyclerView.setAdapter(mAdapter);
/////////////////////////////////////////////////////////////////////////
        LinearLayoutManager linearLayoutManager2 = new LinearLayoutManager(getActivity());
        linearLayoutManager2.setOrientation(LinearLayoutManager.VERTICAL);
        voiceRecycler.setLayoutManager(linearLayoutManager2);
        paths = new ArrayList<>();
        mVoiceAdapter = new VoiceAdpter(R.layout.new_play_voice_item, paths, getActivity());
        voiceRecycler.setAdapter(mVoiceAdapter);
        mVoiceAdapter.setOnItemChildLongClickListener(this);
        //-----------------------------------------------------

        new_recyclerView = view.findViewById(R.id.new_fragment_chat_rv_chat);
        refreshLayout = view.findViewById(R.id.new_fragment_chat_srl_pullrefresh);
        refreshLayout.setEnabled(false);
        layoutManager = new LinearLayoutManager(getActivity());
        new_recyclerView.setLayoutManager(layoutManager);
        itemAdapter = getAdpter();
        itemAdapter.resetRecycledViewPoolSize(new_recyclerView);
        new_recyclerView.setAdapter(itemAdapter);
        EventBus.getDefault().register(this);
        return view;
    }

    protected NewChatAdapter getAdpter() {
        return new NewChatAdapter();
    }

    //拉取事件
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                AVIMMessage message = itemAdapter.getFirstMessage();
                if (null == message) {
                    refreshLayout.setRefreshing(false);
                } else {
                    imConversation.queryMessages(message.getMessageId(), message.getTimestamp(), 20, new AVIMMessagesQueryCallback() {
                        @Override
                        public void done(List<AVIMMessage> list, AVIMException e) {
                            refreshLayout.setRefreshing(false);
                            if (filterException(e)) {
                                if (null != list && list.size() > 0) {
                                    LogUtils.i(list.size()+"");
                                    //todo get mp3 url

                                    itemAdapter.addMessageList(list);
                                    itemAdapter.setDeliveredAndReadMark(imConversation.getLastDeliveredAt(), imConversation.getLastReadAt());
                                    itemAdapter.notifyDataSetChanged();
                                    layoutManager.scrollToPositionWithOffset(list.size() - 1, 0);
                                }
                            }
                        }
                    });
                }
            }
        });
    }


    @Override
    public void onResume() {
        super.onResume();
        if (null != imConversation) {
            NotificationUtils.addTag(imConversation.getConversationId());
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        if (null != imConversation) {
            NotificationUtils.removeTag(imConversation.getConversationId());
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        EventBus.getDefault().unregister(this);
    }

    public void setConversation(final AVIMConversation conversation) {
        imConversation = conversation;
        refreshLayout.setEnabled(true);
        inputBottomBar.setTag(imConversation.getConversationId());
        fetchMessages();
        NotificationUtils.addTag(conversation.getConversationId());
        if (!conversation.isTransient()) {
            if (conversation.getMembers().size() == 0) {
                conversation.fetchInfoInBackground(new AVIMConversationCallback() {
                    @Override
                    public void done(AVIMException e) {
                        if (null != e) {
                            LogUtils.logException(e);
                        }
                        itemAdapter.showUserName(conversation.getMembers().size() > 2);
                    }
                });
            } else {
                itemAdapter.showUserName(conversation.getMembers().size() > 2);
            }
        } else {
            itemAdapter.showUserName(true);
        }


    }

    /**
     * 拉取消息，必须加入 conversation 后才能拉取消息
     */
    private void fetchMessages() {
        imConversation.queryMessages(new AVIMMessagesQueryCallback() {
            @Override
            public void done(List<AVIMMessage> messageList, AVIMException e) {
                if (filterException(e)) {
                    itemAdapter.setMessageList(messageList);
                    new_recyclerView.setAdapter(itemAdapter);
                    itemAdapter.setDeliveredAndReadMark(imConversation.getLastDeliveredAt(),
                            imConversation.getLastReadAt());
                    itemAdapter.notifyDataSetChanged();
                    scrollToBottom();
                    clearUnreadConut();
                }
            }
        });
    }


    /**
     * 滚动 recyclerView 到底部
     */
    private void scrollToBottom() {
        layoutManager.scrollToPositionWithOffset(itemAdapter.getItemCount() - 1, 0);
    }


    /**
     * 输入事件处理，接收后构造成 AVIMTextMessage 然后发送
     * 因为不排除某些特殊情况会受到其他页面过来的无效消息，所以此处加了 tag 判断
     */
    @Subscribe
    public void onEvent(InputBottomBarTextEvent textEvent) {
        if (null != imConversation && null != textEvent) {
//            sendText(textEvent.sendContent);
            try {
                //
                inputBottomBar.setVisibility(View.GONE);
                uplodeAudio(textEvent.sendContent);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 处理推送过来的消息
     * 同理，避免无效消息，此处加了 conversation id 判断
     */
    @Subscribe
    public void onEvent(TypeMessageEvent messageEvent) {
        //TODO 判断类型
        if (null != imConversation && null != messageEvent &&
                imConversation.getConversationId().equals(messageEvent.conversation.getConversationId())) {
            itemAdapter.addMessage(messageEvent.message);
            itemAdapter.notifyDataSetChanged();

            scrollToBottom();
            clearUnreadConut();
        }
    }

    /**
     * 重新发送已经发送失败的消息
     */
    @Subscribe
    public void onEvent(MessageResendEvent resendEvent) {
        if (null != imConversation && null != resendEvent &&
                null != resendEvent.message && imConversation.getConversationId().equals(resendEvent.message.getConversationId())) {
            if (AVIMMessage.AVIMMessageStatus.AVIMMessageStatusFailed == resendEvent.message.getMessageStatus()
                    && imConversation.getConversationId().equals(resendEvent.message.getConversationId())) {
                sendMessage(resendEvent.message, false);
            }
        }
    }
    @Subscribe
    public void onEvent(final MessageUpdatedEvent event) {
        if (null != imConversation && null != event &&
                null != event.message && imConversation.getConversationId().equals(event.message.getConversationId())) {
        }
    }

    /**
     * 处理录音事件
     *
     * @param recordEvent
     */
    @Subscribe
    public void onEvent(InputBottomBarRecordEvent recordEvent) {

        if (recordEvent.audioDuration > 0)
            sendAudio(recordEvent.audioPath, recordEvent.audioDuration);
    }

    /**
     * 发送语音消息
     *
     * @param audioPath
     */
    protected void sendAudio(String audioPath, int Max) {
        VoiceItem item = new VoiceItem();
        item.setMax(Max);
        item.setPath(audioPath);
        paths.add(item);
        mVoiceAdapter.setNewData(paths);
        mVoiceAdapter.notifyDataSetChanged();
    }

    /**
     * 处理输入栏发送过来的事件
     *
     * @param event
     */
    @Subscribe
    public void onEvent(InputBottomBarEvent event) {
        switch (event.eventAction) {
            case InputBottomBarEvent.INPUTBOTTOMBAR_IMAGE_ACTION:
                dispatchPickPictureIntent();
                break;
            case InputBottomBarEvent.INPUTBOTTOMBAR_CAMERA_ACTION:
//                    dispatchTakePictureIntent();
                break;
            default:
                break;
        }

    }

    /**
     * 发送 Intent 跳转到系统图库页面
     */
    private void dispatchPickPictureIntent() {
        Album.image(this) // 选择图片。
                .multipleChoice()
                .requestCode(REQUEST_IMAGE_PICK)
                .camera(true)
                .columnCount(3)
                .selectCount(6)
                .onResult(new Action<ArrayList<AlbumFile>>() {
                    @Override
                    public void onAction(int requestCode, @NonNull ArrayList<AlbumFile> result) {
//                        todo set H W
                        for(int i = 0;i<result.size();i++){
                            BitmapFactory.Options options = new BitmapFactory.Options();
                            options.inJustDecodeBounds = true;
                            Bitmap bitmap = BitmapFactory.decodeFile(result.get(i).getPath(), options); // 此时返回的bitmap为null
                            result.get(i).setHeight(options.outHeight);
                            result.get(i).setWidth(options.outWidth);
                        }
                        files = result;
                        mAdapter.setNewData(result);
                        mAdapter.notifyDataSetChanged();

                    }
                })
                .onCancel(new Action<String>() {
                    @Override
                    public void onAction(int requestCode, @NonNull String result) {
                        LogUtils.i("cancel +" + requestCode);
                    }
                })
                .start();

    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (Activity.RESULT_OK == resultCode) {
            switch (requestCode) {

                case REQUEST_IMAGE_PICK:
//                    List<String> pathList = Album.
//                    sendImage(getRealPathFromURI(getActivity(), data.getData()));
                    break;
                default:
                    break;
            }
        }
    }


    /**
     * 根据 Uri 获取文件所在的位置
     *
     * @param context
     * @param contentUri
     * @return
     */
    private String getRealPathFromURI(Context context, Uri contentUri) {
        if (contentUri.getScheme().equals("file")) {
            return contentUri.getEncodedPath();
        } else {
            Cursor cursor = null;
            try {
                String[] proj = {MediaStore.Images.Media.DATA};
                cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
                if (null != cursor) {
                    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                    cursor.moveToFirst();
                    return cursor.getString(column_index);
                } else {
                    return "";
                }
            } finally {
                if (cursor != null) {
                    cursor.close();
                }
            }
        }
    }

    /**
     * 发送图片消息
     *
     * @param imagePath
     */
    protected void sendImage(String imagePath) {
        try {
            sendMessage(new AVIMImageMessage(imagePath));
        } catch (IOException e) {
            LogUtils.logException(e);
        }
    }

    /**
     * 发送文本消息
     *
     * @param content
     */
    protected void sendText(String content) {
        TeacherData data = new TeacherData();
        data.setType(1000);
        data.setAudio(audio);
        data.setImage(images);
        data.setText(content);
        Gson gson = new Gson();
        String json = gson.toJson(data);
        AVIMTextMessage message = new AVIMTextMessage();
        message.setText(json + "");
        sendMessage(message);
    }

    private void uplodeAudio(final String content) throws FileNotFoundException {
        if (paths.size() == 0) {
            uplodeImage(content);
            return;
        }
        count = 0;
        for (int i = 0; i < paths.size(); i++) {
            final AVFile file = AVFile.withAbsoluteLocalPath("record_"+System.currentTimeMillis()+".mp3", paths.get(i).getPath());
            final int finalI = i;
            file.saveInBackground(new SaveCallback() {
                @Override
                public void done(AVException e) {
                    count++;
                    DataMP3Bean bean = new DataMP3Bean();
                    bean.setUrl(file.getUrl());
                    bean.setObjectId(file.getObjectId());
                    bean.setData(System.currentTimeMillis());
                    bean.setSize((long)file.getMetaData("size"));
                    bean.setDuration((long)paths.get(finalI).getMax());
                    audio.add(bean);
                    LogUtils.d(finalI + "--------------bean----" + images.size());
                    if (count == paths.size() ) {
                        try {
                            uplodeImage(content);
                        } catch (FileNotFoundException e1) {
                            e1.printStackTrace();
                        }
                    }
                }
            }, new ProgressCallback() {
                @Override
                public void done(Integer integer) {
                    // 上传进度数据，integer 介于 0 和 100。
                    Log.i("tag", integer + "");
                }
            });
        }
    }

    private void uplodeImage(final String content) throws FileNotFoundException {
        if (files.size() == 0) {
            sendText(content);
            return;
        }
        count= 0;
        for (int i = 0; i < files.size(); i++) {

            final AVFile file = AVFile.withAbsoluteLocalPath(files.get(i).getPath().replaceAll("/storage/emulated/0/",""), files.get(i).getPath());
            final int finalI = i;
            LogUtils.d(i+"---i===size" + files.size());
            file.saveInBackground(new SaveCallback() {
                @Override
                public void done(AVException e) {
                    count++;
                    DataPhotoBean bean = new DataPhotoBean();
                    bean.setUrl(file.getUrl());
                    bean.setObjectId(file.getObjectId());
                    bean.setSize((long)file.getMetaData("size"));
                    bean.setWidth(files.get(finalI).getWidth());////////////////////////////////////////////////////////////////////////
                    bean.setHeight(files.get(finalI).getHeight());
                    bean.setData(System.currentTimeMillis());
                    images.add(bean);
                    if (count == files.size() ) {
                        sendText(content);
                    }
                }
            }, new ProgressCallback() {
                @Override
                public void done(Integer integer) {
                    // 上传进度数据，integer 介于 0 和 100。
                }
            });
        }
    }

    public void sendMessage(AVIMMessage message) {
        sendMessage(message, true);
    }

    /**
     * 发送消息
     *
     * @param message
     */
    public void sendMessage(final AVIMMessage message, boolean addToList) {
        if (addToList) {
            itemAdapter.addMessage(message);
        }
        itemAdapter.notifyDataSetChanged();
        scrollToBottom();
        AVIMMessageOption option = new AVIMMessageOption();
        option.setReceipt(true);
        imConversation.sendMessage(message, option, new AVIMConversationCallback() {
            @Override
            public void done(AVIMException e) {
                itemAdapter.notifyDataSetChanged();
                if (null != e) {
                    LogUtils.logException(e);
                }
            }
        });
        images.clear();
        audio.clear();
        paths.clear();
        files.clear();
        mVoiceAdapter.setNewData(paths);
        mVoiceAdapter.notifyDataSetChanged();
        mAdapter.setNewData(files);
        mAdapter.notifyDataSetChanged();
        inputBottomBar.setVisibility(View.VISIBLE);
    }

    private boolean filterException(Exception e) {
        if (null != e) {
            LogUtils.logException(e);
            Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
        }
        return (null == e);
    }

    private void clearUnreadConut() {
        if (imConversation.getUnreadMessagesCount() > 0) {
            imConversation.read();
        }
    }


    @Override
    public boolean onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) {
        //todo remove file
        File file = new File(paths.get(position).getPath());
        if (file.exists()) {
            boolean ok = file.delete();
            LogUtils.d("file delet ==" + ok);
        }
        paths.remove(position);
        mVoiceAdapter.setNewData(paths);
        mVoiceAdapter.notifyDataSetChanged();
        return false;
    }
}
